home *** CD-ROM | disk | FTP | other *** search
- /*
- * Serial Module.c
- *
- * This program source code and it's compiled version is
- * Copyright (c) 1991 N. Hawthorn.
- * This program source code and it's compiled version IS NOT IN THE
- * PUBLIC DOMAIN ! Please read the "COPYRIGHT NOTICE / NH" file for details
- * regarding use of this program source code and it's compiled version.
- *
- * This module's name is "serial", it's type is "MOD1", usea resource mover
- * to assign a new number to it, that's why we name our modules !
- *
- * THIS IS A INIT MODULE, IT NEEDS TO BE IN LISTED IN THE "INITMODULES" LIST
- * It only needs to be called as a INIT, it just sets up the serial I/O pointers
- *
- * Notice that we use "Hook Stuff.h" and we do not just "return", but jump to
- * "end" and there set the A4 register before returning.
- *
- */
-
- #define INMAIN
-
- #include <SetUpA4.h>
- #include "MUBBS Module.h"
- #include "Hook Stuff.h"
- #include <SerialDvr.h>
- #include <DeviceMgr.h>
- #include <FileMgr.h>
-
- /*
- #define AinRefNum (-6) ; just for info
- #define AoutRefNum (-7)
- #define BinRefNum (-8)
- #define BoutRefNum (-9)
- */
-
- #define SWITCHNOW 5 /* max times of not switching before a force switch */
-
- /* my globals for this module */
-
- static char inbuffA[1024], /* the serial read buffer locked down */
- inbuffB[1024]; /* the serial read buffer locked down */
-
-
- pascal void main (mode1,G1,P1)
- int mode1;
- struct GS *G1;
- Ptr P1; /* we ignore "P" in this module */
- {
- Handle temph;
- float version = 0.5; /* what version of MUBBS you are compatable with IE: .5 and above */
- RememberA0(); SetUpA4(); /* This sets up the A4 register to access our globals */
- asm { _RecoverHandle }; asm {move.l a0,temph}; HLock(temph); /* locks our module, do this ! */
-
- G=G1; /* This MUST be the first thing you do in main only, it sets up the struct globals */
- mode[u]=mode1; /* set up our mode so that you can read it anywhere */
-
- storeA4(); /* save the value of A4 for later calls, only in this type of SPECIAL module */
-
- switch (mode[u]) { /* any un-handled modes return error from this module */
-
- case 98: /* NOTE that this DOESN'T unlock */
- versionck(version); /* just return after this call, don't modify anything */
- goto skip1; /* DON'T UNLOCK */
- break;
- case 0:
- strcpy (G->programmer,"N Hawthorn"); /* show the programmer's name up to 20 chars*/
- setpointers(); /* init call, set up the pointers now */
- G->moduleresult=99; /* we put 99 here because we need to be called to CLOSE */
- goto skip1; /* DON'T UNLOCK */
- break;
- case 1:
- G->moduleresult=0; /* bye bye call, UNLOCK NOW */
- break;
- default:
- G->moduleresult=1; /* return bad code */
- };
-
- HUnlock(temph); /* unlocks this module, do this ! */
-
- skip1:
- RestoreA4(); /* call this when you are all done */
- }
-
-
- sOpen1 () {
-
- static SerShk *handshake;
- int serConfig, serBlen;
- int err;
-
- getA4();
-
- if (u == G->localuser || u > 1) goto end; /* don't open if it's the local user */
-
- if (u==0) {
- if (err = RAMSDOpen(sPortA)) {
- print("\nC> ERROR ! Cannot open the serial driver A\n");
- }
-
- print("<serial driver A opened> ");
- serConfig=data8+stop10+noParity;
- if (strcmp(G->userbaud[u],"300") == 0) serConfig=serConfig+baud300;
- if (strcmp(G->userbaud[u],"1200") == 0) serConfig=serConfig+baud1200;
- if (strcmp(G->userbaud[u],"2400") == 0) serConfig=serConfig+baud2400;
- if (strcmp(G->userbaud[u],"9600") == 0) serConfig=serConfig+baud9600;
- if (strcmp(G->userbaud[u],"19200") == 0) serConfig=serConfig+baud19200;
- if (err = SerReset(AinRefNum, serConfig)) print("\n ERROR ! calling serial config A\n");
-
- handshake->fXOn = 0; /* no XON/XOFF output flow control */
- handshake->fCTS = 0; /* no CTS (input) hardware handshake */
- handshake->xOn = 0x00; /* XON character */
- handshake->xOff = 0x00; /* XOFF character */
- handshake->errs = 0; /* Ignore input errors */
- handshake->evts = 0; /* No device driver events */
- handshake->fInX = 0; /* no XON/XOFF input flow control */
- handshake->fDTR = 0; /* no DTR (output) hardware handshake */
-
- if (err = SerHShake(AinRefNum, handshake)) print("\nERROR ! calling serialHShake A\n");
- serBlen = 2048; /* set the buffer length */
-
- if (err = SerSetBuf(AinRefNum, &inbuffA, serBlen)) print("\nERROR ! setting up serial buffer A\n");
-
- print("<serial port A configed >\n");
- }
-
- if (u==1) {
- if (err = RAMSDOpen(sPortB)) {
- print("\nERROR ! Cannot open the serial driver B\n");
- }
-
- print("<serial driver B opened> ");
- serConfig=data8+stop10+noParity;
- if (strcmp(G->userbaud[u],"300") == 0) serConfig=serConfig+baud300;
- if (strcmp(G->userbaud[u],"1200") == 0) serConfig=serConfig+baud1200;
- if (strcmp(G->userbaud[u],"2400") == 0) serConfig=serConfig+baud2400;
- if (strcmp(G->userbaud[u],"9600") == 0) serConfig=serConfig+baud9600;
- if (strcmp(G->userbaud[u],"19200") == 0) serConfig=serConfig+baud19200;
- if (err = SerReset(BinRefNum, serConfig)) print("\nERROR ! calling serial config B\n");
-
- handshake->fXOn = 0; /* no XON/XOFF output flow control */
- handshake->fCTS = 0; /* no CTS (input) hardware handshake */
- handshake->xOn = 0x00; /* XON character */
- handshake->xOff = 0x00; /* XOFF character */
- handshake->errs = 0; /* Ignore input errors */
- handshake->evts = 0; /* No device driver events */
- handshake->fInX = 0; /* no XON/XOFF input flow control */
- handshake->fDTR = 0; /* no DTR (output) hardware handshake */
-
- if (err = SerHShake(BinRefNum, handshake)) print("\nERROR ! calling serialHShake B\n");
- serBlen = 2048; /* set the buffer length */
-
- if (err = SerSetBuf(BinRefNum, &inbuffB, serBlen)) print("\nERROR ! setting up serial buffer B\n");
-
- print("<serial port B configed >\n");
- }
- end:
- getoldA4();
- }
-
-
- sClose1 () {
- getA4();
- if (u == G->localuser) goto end; /* don't close if it's the local user */
- if (u==0) RAMSDClose(sPortA);
- if (u==1) RAMSDClose(sPortB);
- print("C> <serial driver %d closed>\n",u);
- end:
- getoldA4();
- }
-
- sin1() /* Returns a character from serial port */
- {
- int keylen,result;
- Byte check; /* used to check the CTS line */
- char buffer[2]; /* a temp buffer for input storage */
- CntrlParam contb; /* the blocks of bytes to do I/O */
- IOParam iob;
-
- getA4();
-
- if (G->local[u]) {
- if (keylen = strlen(G->keyboardbuf) > 0) { /* are there characters waiting ? */
- G->input[u]=G->keyboardbuf[(keylen-1)];
- G->keyboardbuf[(keylen-1)] = 0; /* shorten the string */
- result=TRUE;
- otheruser(FALSE); /* switch if it's time to switch */
- goto end;
- }
- goto none;
- }
-
- if (u != G->localuser) {
- /* some addresses for my info ($9FFFFA) or $50F04022 */
-
- if (u == 0) {
- if (G->carrdet[u] && (check = *(SCCRd + 2) & 0x20)) { /* CTS is bit 5, 1= carr loss */
- print("C> CARRIER LOSS DETECTED DURING INPUT !!\n");
- G->online[u]=FALSE;
- goto none;
- }
- contb.ioRefNum = AinRefNum;
- contb.csCode = 2; /* do a status to see if any chars */
- if (PBStatus(&contb, FALSE)) goto none;
- if (*(long *)&contb.csParam[0]) { /* do the check for characters */
- iob.ioRefNum = AinRefNum;
- iob.ioBuffer = (Ptr)buffer; /* characters waiting, get them */
- iob.ioReqCount = 1;
- if (PBRead(&iob, FALSE)) goto none;
- if (G->nottransfer[u]) {G->input[u] = buffer[0] & 0x7F;} /* strip the 8th bit for text */
- else G->input[u] = buffer[0]; /* G->input[u] is a global variable */
- otheruser(FALSE); /* once and a while switch */
- result=TRUE;
- goto end;
- }
- goto none;
- }
-
- if (u == 1) {
- if (G->carrdet[u] && (check = *(SCCRd + 0) & 0x20)) { /* CTS is bit 5, 1= carr loss */
- print("C> CARRIER LOSS DETECTED DURING INPUT !!\n");
- G->online[u]=FALSE;
- goto none;
- }
- contb.ioRefNum = BinRefNum;
- contb.csCode = 2; /* do a SerGetBuf to see if any chars */
- if (PBStatus(&contb, FALSE)) goto none;
- if (*(long *)&contb.csParam[0]) { /* do the check for characters */
- iob.ioRefNum = BinRefNum;
- iob.ioBuffer = (Ptr)buffer; /* characters waiting, get them */
- iob.ioReqCount = 1;
- if (PBRead(&iob, FALSE)) goto none;
- if (G->nottransfer[u]) {G->input[u] = buffer[0] & 0x7F;} /* strip the 8th bit for text */
- else G->input[u] = buffer[0]; /* G->input[u] is a global variable */
- otheruser(FALSE); /* once and a while switch */
- result=TRUE;
- goto end;
- }
- }
- } /* close the "BIG" if */
-
- none:
- otheruser(TRUE); /* switch NOW, don't wait when we arn't doing anything */
- result=FALSE; /* no characters waiting */
-
- end:
- getoldA4();
- return result;
- }
-
- sout1(x) /* sends a character to serial port */
- unsigned char x;
- {
- int result;
- char buffer[2]; /* a temp buffer for input storage */
- Byte check; /* used to check the CTS line */
- IOParam iob;
-
- getA4();
-
- if (G->monitor[u]) {if (x != 0x0A) printout(x);} /* for monitoring */
-
- iob.ioCompletion = 0L; /* set these up now */
- iob.ioBuffer = (Ptr)buffer;
- iob.ioReqCount = 1;
-
- loop:
- if ( u != G->localuser) {
- if (u == 0) {
- if ( !G->nocheck[u] ){
- if (G->carrdet[u] && (check = *(SCCRd + 2) & 0x20)) { /* CTS is bit 5, 1= carr loss */
- print("C> CARRIER LOSS DETECTED DURING ** OUTPUT ** !!\n");
- G->cancel[u]=TRUE;
- G->online[u]=FALSE;
- goto none;
- }
- }
- while(TRUE) {
- if (check = *(SCCRd + 2) & 0x04) break; /* Tx Empty is bit 2, 1= empty */
- otheruser(TRUE); /* switch now, we arn't doing nothin */
- }
- buffer[0]=x;
- iob.ioRefNum = AoutRefNum;
- PBWrite(&iob, TRUE); /* asynchronous */
- otheruser(FALSE); /* make sure we switch once and a while */
- result=TRUE;
- goto end;
- }
-
- if (u == 1) {
- if ( !G->nocheck[u] ){
- if (G->carrdet[u] && (check = *(SCCRd + 0) & 0x20)) { /* CTS is bit 5, 1= carr loss */
- print("C> CARRIER LOSS DETECTED DURING ** OUTPUT ** !!\n");
- G->cancel[u]=TRUE;
- G->online[u]=FALSE;
- result=FALSE;
- goto end;
- }
- }
- while(TRUE) {
- if (check = *(SCCRd + 0) & 0x04) break; /* Tx Empty is bit 2, 1= empty */
- otheruser(TRUE); /* switch now, we arn't doing nothin */
- }
- buffer[0]=x;
- iob.ioRefNum = BoutRefNum;
- PBWrite(&iob, TRUE); /* asynchronous */
- otheruser(FALSE); /* make sure we switch once and a while */
- result=TRUE;
- goto end;
- }
- }
- otheruser(FALSE); /* if it's the local user, we did print, so it's OK */
- result=TRUE;
- goto end;
-
- none:
- otheruser(TRUE); /* switch now if we arn't doing anything */
- result=FALSE;
-
- end:
- getoldA4();
- return result;
- }
-
- sflush1 () /* reads all input data until none avail */
- {
- IOParam iob;
-
- getA4();
-
- if (G->local[u]) {
- G->keyboardbuf[0]=0; /* reset keyboard buffer */
- G->input[u]=0;
- goto end;
- }
-
- if (u == G->localuser || u > 1) goto end; /* don't do it if it's the local user */
-
- if (u == 0) {
- iob.ioRefNum = AinRefNum;
- iob.ioCompletion = 0;
- PBKillIO(&iob, FALSE);
- G->input[u]=0; /* clear the old data */
- }
- if (u == 1) {
- iob.ioRefNum = BinRefNum;
- iob.ioCompletion = 0;
- PBKillIO(&iob, FALSE);
- G->input[u]=0; /* clear the old data */
- }
-
- end:
- otheruser(FALSE);
- getoldA4();
- }
-
- out1(x)
- unsigned char x;
- {
- Byte i;
- int a,c,result;
-
- getA4();
-
- result=TRUE;
- G->cancel[u]=FALSE;
- if (G->nottransfer[u]){
- if ( !G->nocheck[u] ){
- if (sin1()){
- if ((G->input[u] & 0x1F) == 0x13) { /* CTL S, S, 3 and s */
- sflush1();
- in1(); /* wait for another keypress, if none, continue anyway */
- sflush1();
- }
- else {
- if ((G->input[u] & 0x1F) == 0x03) { /* ctl C, C, # and c */
- sflush1();
- G->cancel[u]=TRUE; /* return showing that we have been canceled */
- }
- }
- }
- if (x == 0x0A) { /* look for the LF after a CR */
- if (G->userlines[u] && !G->cont[u]) { /* if it's not 0 */
- if (++G->linecnt[u] >= G->userlines[u]){
- sout1(x); /* do the LF now */
- c = G->input[u]; /* save the old input value */
- G->linecnt[u] = 1; /* reset the line count */
- cmd1noecho("Cancel, No (pause):"); /* NO ECHO HERE !! */
- i = G->input[u];
- if (i == 'C' || i == 'c') {G->cancel[u]=TRUE;} /* cancel the output */
- if (i == 'N' || i == 'n') {G->cont[u]=TRUE;}
- a=0;
- while (a++ < 19) {
- sout1('\b');
- sout1(' ');
- sout1('\b');
- } /* get rid of line */
- G->input[u] = c; /* return the old input value */
- G->linecnt[u] = 1; /* reset the line count */
- goto end; /* skip the output */
- }
- }
- }
- }
- }
- result=sout1(x);
- end:
- getoldA4();
- return result;
- }
-
- in1() /* returns true if a character is waiting, false for timeout */
- {
- long int time1;
- int warn,result;
- Byte check; /* used to check the CTS line */
-
- getA4();
-
- time1=Time;
- warn=0;
- if (G->local[u]) showline(); /* show the whole line line now, on the mac screen */
-
- inloop: /* it will return like a time out if carrier is lost */
-
- if ( ! sin1()) { /* if it's zero (no character) then */
- if(!G->online[u]) {
- result=FALSE;
- goto end;
- }
- if (G->chatmode[u] > 0) { /* are we being chatted ??
- if(!module(2,"chat",0L) G->chatmode[u]=0; /* call the chat module */
- time1=Time; /* RESET the clock !! */
- }
- if ((Time-time1)<G->maxtime[u] ) goto inloop;
- warn++;
- time1=Time;
- if (warn == 1) send("]Warning #1 inactivity timeout in %d seconds..]",(G->maxtime[u]*2));
- if (warn == 2) send("]WARNING #2 INACTIVITY TIMEOUT IN %d SECONDS !!]",G->maxtime[u]);
- if (warn == 3) {
- send("]** INACTIVITY TIMEOUT, AUTO LOG OUT IN PROGRESS **]");
- G->online[u]=FALSE;
- result=FALSE;
- goto end;
- }
- goto inloop;
- };
- result=TRUE;
-
- end:
- getoldA4();
- return result;
- }
-
-
- setpointers(){ /* that's all this does ! */
-
- G->seropen = sOpen1;
- G->serclose = sClose1;
- G->serin = sin1;
- G->serout = sout1;
- G->serflush = sflush1;
- G->in = in1;
- G->out = out1;
-
- /* block serial in / out will go here when implimented */
-
- }
-
-
-
-